﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Ignitron.EEngine.Model;
using SharpDX;
using SharpDX.Direct3D11;

namespace Ignitron.EEngine.Adapters.DX.Graphics
{
    /// <summary>
    /// Sub-classed SharpDX model
    /// </summary>
    internal class SharpDXModel: EModel
    {
        /// <summary>
        /// D3D Device
        /// </summary>
        private Device mDevice;

        /// <summary>
        /// The window handle
        /// </summary>
        private IntPtr mWindowHandle;
        
        // DEBUG
        private Camera mCamera;

        /// <summary>
        /// The primitives renderer reference
        /// </summary>
        private PrimitivesRenderer mPrimitivesRenderer;

        /// <summary>
        /// The manager of lighting
        /// </summary>
        private LightingManager mLightingManager;

        /// <summary>
        /// Shader objects
        /// </summary>
        private TextureShader mTextureShader;
        private LightingShader mLightingShader;


        /// <summary>
        /// Model constructor
        /// </summary>
        public SharpDXModel(Device device, IntPtr windowHandle, Camera camera, PrimitivesRenderer renderer, LightingManager lightingManager,
                            TextureShader textureShader, LightingShader lightingShader)
        {
            mDevice = device;
            mWindowHandle = windowHandle;
            mCamera = camera;
            mPrimitivesRenderer = renderer;
            mLightingManager = lightingManager;
            mTextureShader = textureShader;
            mLightingShader = lightingShader;
        }

        /// <summary>
        /// Create our platform specific mesh
        /// </summary>
        protected override EMesh CreateMesh()
        {
            return new SharpDXMesh(mDevice, mWindowHandle, mCamera, mPrimitivesRenderer, mLightingManager, mTextureShader, mLightingShader);
        }

        /// <summary>
        /// Rendering method
        /// </summary>
        internal void Render(Matrix world, ShaderResourceView texture)
        {
            foreach (EMesh mesh in mMeshes)
            {
                (mesh as SharpDXMesh).Render(world, texture);
            }
        }

        /// <summary>
        /// Method for rendering normal vectors
        /// </summary>
        internal void RenderNormals(Matrix world, Vector4 color, float magnitude)
        {
            foreach (EMesh mesh in mMeshes)
            {
                (mesh as SharpDXMesh).RenderNormals(world, color, magnitude);
            }
        }

        /// <summary>
        /// Frees the resources of the model
        /// </summary>
        public void Shutdown()
        {
            // free resources of all meshes
            for (int i = 0; i < mMeshes.Count; i++)
            {
                (mMeshes[i] as SharpDXMesh).Shutdown();
            }

            mMeshes.Clear();
        }
    }
}
